/**
 * representation of Unternehmen
 * @author Lukas Koell
 * @author Johannes Riedmann
 * @author David Medenjak
 */

public class Unternehmen extends Thread {

    /** kuehlhaus for Wildschweinjaeger's units */
    private Lager kuehlhaus;
    /** tisch for Koch's units */
    private Lager tisch;
    /** steinbruch for Baumfaeller's units */
    private Lager steinbruch;
    /** dorfplatz for Logistiker's units */
    private Dorfplatz dorfplatz;
    /** number of runs the Wildschweinjaeger has to accomplish */
    private int runs;
    /** total number of runs of all Wildschweinjaegers */
    private int numberOfRuns;
    /** contains all workers of the company */
    private Thread[] threads;

    public Unternehmen(int runs) {
        this.kuehlhaus = new Lager(1);
        this.tisch = new Lager(2);
        this.steinbruch = new Lager(1);
        this.dorfplatz = new Dorfplatz(1000);
        
        kuehlhaus.setName("Kuehlhaus");
        tisch.setName("Tisch");
        steinbruch.setName("Steinbruch");
        dorfplatz.setName("Dorfplatz");
        threads = new Thread[10];
        this.runs = runs;

        this.dorfplatz.setUnternehmen(this);
    }
    
    public Unternehmen(int runs, Lager kuehlhaus, Lager tisch, Lager steinbruch, Dorfplatz dorfplatz) {
        kuehlhaus.setName("Kuehlhaus");
        tisch.setName("Tisch");
        steinbruch.setName("Steinbruch");
        dorfplatz.setName("Dorfplatz");
        
        this.kuehlhaus = kuehlhaus;
        this.tisch = tisch;
        this.steinbruch = steinbruch;
        this.dorfplatz = dorfplatz;
        this.dorfplatz.setUnternehmen(this);
        this.runs = runs;
        
        threads = new Thread[10];
    }

    @Override
    public void run() {
        WildschweinJaeger w1 = new WildschweinJaeger("Wildschweinjaeger1", this.kuehlhaus, runs);
        WildschweinJaeger w2 = new WildschweinJaeger("Wildschweinjaeger2", this.kuehlhaus, runs);
        numberOfRuns = w1.getRuns() + w2.getRuns();

        Konsument k1 = new Konsument("Koch", this.tisch, 5, this.kuehlhaus, 1);

        Konsument b1 = new Konsument("Baumfaeller1", this.steinbruch, 1, this.tisch, 1);
        Konsument b2 = new Konsument("Baumfaeller2", this.steinbruch, 1, this.tisch, 1);
        Konsument b3 = new Konsument("Baumfaeller3", this.steinbruch, 1, this.tisch, 1);
        Konsument b4 = new Konsument("Baumfaeller4", this.steinbruch, 1, this.tisch, 1);
        Konsument b5 = new Konsument("Baumfaeller5", this.steinbruch, 1, this.tisch, 1);

        Konsument l1 = new Konsument("Logistiker1", this.dorfplatz, 2, this.steinbruch, 2);
        Konsument l2 = new Konsument("Logistiker2", this.dorfplatz, 2, this.steinbruch, 2);

        w1.start();
        w2.start();
        k1.start();
        b1.start();
        b2.start();
        b3.start();
        b4.start();
        b5.start();
        l1.start();
        l2.start();

        threads[0] = w1;
        threads[1] = w2;
        threads[2] = k1;
        threads[3] = b1;
        threads[4] = b2;
        threads[5] = b3;
        threads[6] = b4;
        threads[7] = b5;
        threads[8] = l1;
        threads[9] = l2;
    }

    /**
     * testing regular closure of Unternehmen
     */
    public void testTermination() {
        if (numberOfRuns * 5 == this.dorfplatz.getStorage()) {
            kill();
        }
    }

    /**
     * fires all workers (interrupting threads) and prints a report
     * that shows the content of the storages
     */
    public void kill() {
        System.out.println(getReport());
        
        for (Thread thread : threads) {
            thread.interrupt();
        }        
    }
    
    /**
     * @return string representation of all the stores with the number of containing units
     */
    public String getReport() {
        String ret = "Kuehlhaus: " + kuehlhaus.getStorage() + "\n";
        ret += "Tisch: " + tisch.getStorage() + "\n";
        ret += "Steinbruch: " + steinbruch.getStorage() + "\n";
        ret += "Dorfplatz: " + dorfplatz.getStorage() + "\n";
        return ret;
    }
}
